package interceptcrossing.ui;

import interceptcrossing.Abscissa;
import interceptcrossing.Intercept;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.Collection;

/**
 * @author: Igor Botyan
 * @date: May 7, 2010
 */
public class DebugWindow extends JDialog {

	private DebugWindowDirector debugWindowDirector;
	private MainWindowDirector mainWindowDirector;
	private SweptLineStatusPanel sweptLineStatusPanel;
	private AbscissaLinePanel abscissaLinePanel;
	private DebugPaintPanel paintPanel;
	private JSplitPane paintAndTreeSplitPane;
	private JSplitPane paintAndAbscissaLineSplitPane;
	private JToolBar toolBar;
	private JButton toStartButton;
	private JButton previousButton;
	private JButton nextButton;
	private JButton toEndButton;
	private JButton stopButton;

	public DebugWindow(Frame owner, MainWindowDirector mainWindowDirector) {
		super(owner, "Пошаговый режим", true);

		this.mainWindowDirector = mainWindowDirector;
		this.debugWindowDirector
			= new DebugWindowDirector(this.mainWindowDirector.getIntercepts());
		this.sweptLineStatusPanel = new SweptLineStatusPanel(this.debugWindowDirector);
		this.paintPanel = new DebugPaintPanel(this.debugWindowDirector);
		this.abscissaLinePanel = new AbscissaLinePanel(this.debugWindowDirector);

		this.paintAndAbscissaLineSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
			this.paintPanel, this.abscissaLinePanel);

		this.paintAndTreeSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
			this.paintAndAbscissaLineSplitPane, this.sweptLineStatusPanel);

		this.initToolBar();
		this.initLayout();
		this.initActions();

		super.setSize(owner.getWidth(), owner.getHeight());
		super.setMinimumSize(super.getSize());
		super.setLocationRelativeTo(owner);

		this.updateControls();
	}

	private void initLayout() {
		Container contentPane = this.getContentPane();

		contentPane.setLayout(new GridBagLayout());

		contentPane.add(this.toolBar, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0,
			GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL,
			new Insets(5, 5, 5, 5), 0, 0));
		contentPane.add(this.paintAndTreeSplitPane,
			new GridBagConstraints(1, 2, 1, 1, 1.0, 1.0,
				GridBagConstraints.CENTER, GridBagConstraints.BOTH,
				new Insets(5, 5, 5, 5), 0, 0));
	}

	private void initToolBar() {
		this.toolBar = new JToolBar();
		this.toolBar.setFloatable(false);

		this.toStartButton = new JButton(new ImageIcon(DebugWindow.class.getResource("go_first.png")));
		this.previousButton = new JButton(new ImageIcon(DebugWindow.class.getResource("go_previous.png")));
		this.nextButton = new JButton(new ImageIcon(DebugWindow.class.getResource("go_next.png")));
		this.toEndButton = new JButton(new ImageIcon(DebugWindow.class.getResource("go_last.png")));
		this.stopButton = new JButton(new ImageIcon(DebugWindow.class.getResource("stop.png")));

		this.toStartButton.setToolTipText("Вернуться к первому шагу");
		this.toStartButton.setEnabled(false);
		this.previousButton.setToolTipText("Вернуться к предыдущему шагу");
		this.previousButton.setEnabled(false);
		this.nextButton.setToolTipText("Перейти к следующему шагу");
		this.toEndButton.setToolTipText("Перейти к последнему шагу");
		this.stopButton.setToolTipText("Остановить пошаговое выполнение и закрыть окно");

		this.toolBar.add(this.toStartButton);
		this.toolBar.add(this.previousButton);
		this.toolBar.add(this.nextButton);
		this.toolBar.add(this.toEndButton);
		this.toolBar.add(this.stopButton);
	}

	private void initActions() {
		this.addComponentListener(new ComponentAdapter() {

			@Override
			public void componentResized(ComponentEvent e) {
				int paHeight = paintAndAbscissaLineSplitPane.getSize().height;
				paintAndAbscissaLineSplitPane.setDividerLocation((paHeight * 0.95) / paHeight);

				int ptHeight = paintAndTreeSplitPane.getSize().height;
				paintAndTreeSplitPane.setDividerLocation((ptHeight * 0.8) / ptHeight);
			}
		});

		this.toStartButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				DebugWindow.this.debugWindowDirector.goToStart();
			}
		});

		this.previousButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				DebugWindow.this.debugWindowDirector.previousStep();
			}
		});

		this.nextButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				DebugWindow.this.debugWindowDirector.nextStep();
			}
		});

		this.toEndButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				DebugWindow.this.debugWindowDirector.goToEnd();
			}
		});

		this.stopButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				DebugWindow.this.setVisible(false);
			}
		});

		this.debugWindowDirector.addListener(new DebugWindowDirector.Listener() {

			public void currentAbscissaChanged(Abscissa abscissa, Collection<Intercept> aboveIntercepts,
			                                   Collection<Intercept> underIntercepts) {
				DebugWindow.this.updateControls();
			}
		});
	}

	private void updateControls() {
		boolean canPrevious = this.debugWindowDirector.hasPreviousStep();
		boolean canNext = this.debugWindowDirector.hasNextStep();

		this.toStartButton.setEnabled(canPrevious);
		this.previousButton.setEnabled(canPrevious);
		this.nextButton.setEnabled(canNext);
		this.toEndButton.setEnabled(canNext);
	}
}
